1 module hunt.http.session; 2 3 import hunt.cache; 4 import hunt.utils.time; 5 6 import std.json; 7 import std.conv; 8 import std.digest.sha; 9 import std.format; 10 import std.datetime; 11 import std.random; 12 import core.cpuid; 13 import std.string; 14 import std.experimental.logger; 15 16 class Session 17 { 18 private string _sessionId; 19 private JSONValue _sessions; 20 private SessionStorage _sessionStorage; 21 22 this(SessionStorage sessionStorage) 23 { 24 this._sessionStorage = sessionStorage; 25 this._sessionId = _sessionStorage.generateSessionId(); 26 this._sessions = parseJSON(_sessionStorage.get(_sessionId)); 27 } 28 this(string sessionId,SessionStorage sessionStorage) 29 { 30 this._sessionId = sessionId; 31 this._sessionStorage = sessionStorage; 32 this._sessions = parseJSON(_sessionStorage.get(_sessionId)); 33 } 34 35 Session set(T)(string key, T value) 36 { 37 _sessions[key] = value.to!string; 38 _sessionStorage.set(_sessionId, _sessions.toString); 39 return this; 40 } 41 42 string get(string key) 43 { 44 try 45 { 46 return _sessions[key].str; 47 } 48 catch (Exception e) 49 { 50 return string.init; 51 } 52 } 53 54 T get(T)(string key, T defaultValue) 55 { 56 string v = get(key); 57 58 try 59 { 60 return to!T(v); 61 } 62 catch (Exception e) 63 { 64 return defaultValue; 65 } 66 } 67 68 void remove(string key) 69 { 70 JSONValue json; 71 72 foreach (string _key, ref value; _sessions) 73 { 74 if (_key != key) 75 { 76 json[_key] = value; 77 } 78 } 79 80 _sessions = json; 81 _sessionStorage.set(_sessionId, _sessions.toString); 82 } 83 84 string[] keys() 85 { 86 string[] ret; 87 88 foreach (string key, value; _sessions) 89 { 90 ret ~= key; 91 } 92 93 return ret; 94 } 95 96 string sessionId() 97 { 98 return _sessionId; 99 } 100 } 101 102 class SessionStorage 103 { 104 105 this(UCache cache) 106 { 107 _cache = cache; 108 } 109 110 111 alias set = put; 112 113 bool put(string key, string value, int expire) 114 { 115 _cache.put!string(getRealAddr(key), value, expire); 116 return true; 117 } 118 119 bool put(string key, string value) 120 { 121 return put(key, value, _expire); 122 } 123 124 string get(string key) 125 { 126 return cast(string)_cache.get!string(getRealAddr(key)); 127 } 128 129 alias isset = containsKey; 130 bool containsKey(string key) 131 { 132 return _cache.containsKey(key); 133 } 134 135 alias del = erase; 136 alias remove = erase; 137 bool erase(string key) 138 { 139 return _cache.remove(getRealAddr(key)); 140 } 141 142 143 string generateSessionId(string sessionName = "hunt_session") 144 { 145 import hunt.utils.random; 146 SHA1 hash; 147 hash.start(); 148 hash.put(getRandom); 149 ubyte[20] result = hash.finish(); 150 string str = toLower(toHexString(result)); 151 152 JSONValue json; 153 json[sessionName] = str; 154 json["_time"] = getCurrUnixStramp + _expire; 155 156 set(str,json.toString,_expire); 157 158 return str; 159 } 160 161 162 void setPrefix(string prefix) 163 { 164 _prefix = prefix; 165 } 166 167 void setExpire(int expire) 168 { 169 _expire = expire; 170 } 171 172 string getRealAddr(string key) 173 { 174 return _prefix ~ key; 175 } 176 177 int expire() 178 { 179 return _expire; 180 } 181 182 183 184 private 185 { 186 string _prefix; 187 string _sessionId; 188 189 int _expire; 190 UCache _cache; 191 } 192 }